#ifndef TREEGEN_H
#define TREEGEN_H
#include "common.h"
#include <vector>
#include "renderer.h"
#define PI 3.14
//modifies portion sent to terminal vs aux.
#define LAMBDA .58
//alpha modifies resource at base
#define ALPHA 2
//determines rate of diameter growth (smaller the fatter)
#define DIAMETER_RATE 2.8
// >0 for growth influenced up, <0 for growth skewed down
#define TROPISM .3
//default angle of auxilary branch
#define AUX_ANGLE .75
//weight of default aux direction in branch growth
#define AUX_WEIGHT 3
//weight of default term direction in branch growth
#define TERM_WEIGHT 3
//scale adujst for term and aux directions
#define TLENGTH 7
#define ALENGTH 7
#define SHED_THRES .2

class Shadow2D;

enum Fate{FLOWER, METAMER, DORMANT, ABORT};
enum BudType{Auxilary, Terminal};
//Bud is same as node
struct Bud{
    Fate bud_fate;
    BudType bud_type;
    int budsAbove;
    float exposure;
    float darken;
    int season;
    //unit vector in direction internode is pointing
    float3 direction;
    //pertain to internode below node
    float diameter;
    float length;
    //the angle at which the internode is relative to the axis. Theta is defined to be PI/2 at verticle.
    //(For 2D)
    float phi;
    float theta;
    //refer to start and end positions of internode below this one
    float3 start;
    float3 end;
    bool leaf;
    int i,j,k; //shadow prop voxel coordinates, where the tree root is 0,0,0
    //refer to terminal and auxilary buds. If NULL, that means this node has a bud of that type
    //here, otherwise it means that bud has already grown and there is a child node.
    Bud *term, *aux; // remember to set these to NULL at construction
    //Q resource for terminal and auxBuds, and internode
    float tQ, aQ, iQ;
    //resource:
    float resource, ares, tres;

    float auxAngle;
    float3 auxDir;
    //direction of optimum growth
    float3 tV, aV;
    int spaceColIndex; // Diem: each bud is associated with a unique index.
    Bud(){//TODO: finish constructor
        term = NULL;
        aux = NULL;
    }
};

class TreeGen
{
public:
    TreeGen();
    ~TreeGen();
    Bud *treeRoot;

    void freeTree(Bud *root);

protected:
    void basipetalBH(Bud *b);
    void passBH();
    void pass2BH(Bud *b);
    void createBudFromBud(Bud *b, Bud *out);
    virtual void initializeBud(Bud *b) = 0;
    float3 _tropism, _wind;
    void produceShoots(Bud *b);
    //only to be used with shadow propogation
    void shedBranches(Bud *b);

};

/**
class TreeGen3D
{
public:
    TreeGen3D(float3 start);
    ~TreeGen3D(){
        freeTree(treeRoot);
    }
    void freeTree(Bud*root);
    Bud *treeRoot;
    void genTree();
    void updateTree();
private:
    float3 findDirection();
    void applyTropism();
    void calculateShadow();
    void applyShedding();
    void chooseBudFate();
    void calculateBranchDiameter();
    void createBudFromBud(Bud *b, Bud *out);
    //question, how does the progressive diameter thing work, what counts as one segment of branch?
    //what should each bud store, or number ofnodes above it, when one is added it adds/subtracts from subbranches
};

*/
#endif // TREEGEN_H
